package tree;

import java.util.ArrayList;
import java.util.List;

/**
 * Implementation of a tree. A tree has a root node and a list of all
 * of its nodes.
 * 
 * @author Simon Dehne
 *
 */
public class Tree {
	
	private Node root;
	private List<Node> nodes;
	
	/*
	 * Constructor takes a node which will be the root of the tree.
	 * Adds the root to the list of nodes in the tree.
	 */
	public Tree() {
		this.nodes = new ArrayList<Node>();
	}
	
	public void setRoot(Node root) {
		this.root = root;
		nodes.add(root);
	}
	public Node getRoot() {
		return root;
	}
	
	public void addNode(Node node) {
		nodes.add(node);
	}
	
	public List<Node> getNodes() {
		return nodes;
	}
	
	/**
	 * Finds a node by its x and y position
	 * 
	 * @param x
	 * @param y
	 * @return The node if any is found, null if none is found.
	 */
	public Node getNode(int x, int y) {
		
		for(int i=0; i<nodes.size(); i++) {
			if(nodes.get(i).getX() == x && nodes.get(i).getY() == y) {
				return nodes.get(i);
			}
		}
		
		return null;
		
	}
	
	/**
	 * Gets the adjacent nodes for a node with the specified coordinates.
	 * 
	 * @param x
	 * @param y
	 * @return A list of neighbors, if neighbors exist.
	 */
	public List<Node> getNeighborsForNode(int x, int y) {
		
		// The node for which neighbors should be found
		Node node = getNode(x, y);

		// If no such node exists in the first place, get out
		if(node == null) {
			return null;
		}
		
		// Create a list of neighbors
		List<Node> neighbors = new ArrayList<Node>();
		
		/*
		 * Look at this:
		 * 
		 * ***************************
		 * *** 2,3 *** 3,3 *** 4,3 ***
		 * *** 2,4 *** 3,4 *** 4,4 ***
		 * *** 2,5 *** 3,5 *** 4,5 ***
		 * ***************************
		 * 
		 * If we want to find all of the neighbors for 3,4,
		 * we simply have to check if nodes exist, such that:
		 * 
		 * (3,4) - (1, 1)          [neighbor to the upper left]
		 * (3,4) - (1, 0)          [neighbor to the left]
		 * (3,4) - (1, 0) + (0, 1) [neighbor to the lower left]
		 * (3,4) - (0, 1)          [neighbor upwards]
		 * (3,4) + (0, 1)          [neighbor downwards]
		 * (3,4) + (1, 0) - (0, 1) [neighbor to the upper right]
		 * (3,4) + (1,0)           [neighbor to the right]
		 * (3,4) + (1, 1)          [neighbor to the lower right]
		 * 
		 * 8 possible neighbors all in all. Check for all of those and add
		 * them to the neighbor list if they exist.
		 * 
		 * TODO: THIS LOOKS HORRIBLE HOLY SHIT
		 */
		
		Node upperLeft = getNode(node.getX()-1, node.getY()-1);
		Node left = getNode(node.getX()-1, node.getY());
		Node lowerLeft = getNode(node.getX()-1, node.getY()+1);
		Node up = getNode(node.getX(), node.getY()-1);
		Node down = getNode(node.getX(), node.getY()+1);
		Node upperRight = getNode(node.getX()+1, node.getY()-1);
		Node right = getNode(node.getX()+1, node.getY());
		Node lowerRight = getNode(node.getX()+1, node.getY()+1);
		
		if(upperLeft != null) neighbors.add(upperLeft);
		if(left != null) neighbors.add(left);
		if(lowerLeft != null) neighbors.add(lowerLeft);
		if(up != null) neighbors.add(up);
		if(down != null) neighbors.add(down);
		if(upperRight != null) neighbors.add(upperRight);
		if(right != null) neighbors.add(right);
		if(lowerRight != null) neighbors.add(lowerRight);
		
		return neighbors;
	}

}
